package kms

import (
	"fmt"
	"github.com/wuzfei/go-helper/maps"
	"sort"
)

const contactStr = "&"

type Request interface {
	action() string
}

type Response interface {
	Success() bool
	Error() error
	setRaw(r []byte)
}

type ReqCommon struct {
	Payload   Request `json:"payload"`
	Appid     string  `json:"appid"`
	Timestamp string  `json:"timestamp"`
}

type ResCommon struct {
	raw     []byte `json:"-"`
	Code    int    `json:"code"`
	Message string `json:"message,omitempty"`
}

func (receiver *ResCommon) Success() bool {
	return receiver.Code == 200
}

func (receiver *ResCommon) Error() error {
	if receiver.Success() {
		return nil
	}
	return Error.New(receiver.Message)
}

func (receiver *ResCommon) String() string {
	return string(receiver.raw)
}
func (receiver *ResCommon) Bytes() []byte {
	return receiver.raw
}

func (receiver *ResCommon) setRaw(r []byte) {
	receiver.raw = r
}

func MapAnyToString(param map[string]any) string {
	if len(param) == 0 {
		return ""
	}
	keys := maps.Keys(param)
	sort.Strings(keys)
	str := ""
	for i := range keys {
		str += AnyToString(keys[i], param[keys[i]]) + contactStr
	}
	return str[:len(str)-1]
}

func AnyToString(key string, param any) string {
	str := ""
	switch param.(type) {
	case map[string]any:
		str += key + "=" + MapAnyToString(param.(map[string]any))
	case []any:
		for _i := range param.([]any) {
			_key := fmt.Sprintf("%s[%d]", key, _i)
			str += AnyToString(_key, param.([]any)[_i])
		}
	case nil:
		str += key + "=" + ""
	default:
		str += key + "=" + fmt.Sprintf("%v", param)
	}
	return str
}
